package com.cloudeasy.user.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloudeasy.api.enums.ResultCodeEnum;
import com.cloudeasy.api.exception.CloudEasyException;
import com.cloudeasy.user.mapper.RolePermissionMapper;
import com.cloudeasy.user.po.Permission;
import com.cloudeasy.user.po.RolePermission;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
@Transactional(rollbackFor = Exception.class)
public class RolePermissionService extends ServiceImpl<RolePermissionMapper, RolePermission> {
    private final RoleService roleService;

    private final PermissionService permissionService;

    public RolePermissionService(RoleService roleService, PermissionService permissionService) {
        this.roleService = roleService;
        this.permissionService = permissionService;
    }

    /**
     * 根据角色Id查询角色权限记录
     *
     * @param roleIds 角色Id列表
     * @return {@link List<RolePermission>}
     */
    public List<RolePermission> listByRoleIds(List<String> roleIds) {
        QueryWrapper<RolePermission> queryWrapper = new QueryWrapper<>();
        if (roleIds != null && roleIds.size() > 0) {
            queryWrapper.in("role_id", roleIds);
        }
        return this.list(queryWrapper);
    }

    /**
     * 根据权限Id查询角色权限记录
     *
     * @param permissionIds 权限Id列表
     * @return {@link List<RolePermission>}
     */
    public List<RolePermission> listByPermissionIds(List<String> permissionIds) {
        QueryWrapper<RolePermission> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("permission_id", permissionIds);
        return this.list(queryWrapper);
    }

    /**
     * 为角色赋予权限
     *
     * @param roleId       角色Id
     * @param permissionId 权限Id
     * @param authorize    可授权
     * @return {@link Boolean}
     */
    public Boolean save(String roleId, String permissionId, Boolean authorize) {
        if (roleService.getById(roleId) == null || permissionService.getById(permissionId) == null) {
            throw new CloudEasyException(ResultCodeEnum.ID_NOT_EXISTS);
        }
        if (getByRoleIdAndPermissionId(roleId, permissionId) != null) {
            throw new CloudEasyException(ResultCodeEnum.REPEAT_ERROR);
        }
        RolePermission rolePermission = RolePermission.builder()
                .roleId(roleId)
                .permissionId(permissionId)
                .authorize(authorize == null ? false : authorize)
                .build();
        return this.save(rolePermission);
    }

    /**
     * 判断是否可以授权
     *
     * @param roleIds      角色Id列表
     * @param permissionId 权限Id
     * @return {@link Boolean}
     */
    public Boolean canAuthorize(List<String> roleIds, String permissionId) {
        QueryWrapper<RolePermission> queryWrapper = new QueryWrapper<>();
        List<String> permissionIds = permissionService.findSamePermissions(permissionId).stream().map(Permission::getId).collect(Collectors.toList());
        queryWrapper.in("role_id", roleIds)
                .in("permission_id", permissionIds)
                .eq("authorize", true);
        return this.list(queryWrapper).size() > 0;
    }

    /**
     * 为角色赋予权限
     *
     * @param roleId       角色Id
     * @param permissionId 权限Id
     * @param authorize    可授权
     * @return {@link Boolean}
     */
    public Boolean changeAuthorize(String roleId, String permissionId, Boolean authorize) {
        if (authorize == null) {
            return false;
        }
        if (getByRoleIdAndPermissionId(roleId, permissionId) == null) {
            throw new CloudEasyException(ResultCodeEnum.ID_NOT_EXISTS);
        }
        UpdateWrapper<RolePermission> updateWrapper = new UpdateWrapper<>();
        updateWrapper.set("authorize", authorize)
                .eq("role_id", roleId)
                .eq("permission_id", permissionId);
        return this.update(updateWrapper);
    }

    /**
     * 移除角色的权限
     *
     * @param roleId       角色Id
     * @param permissionId 权限Id
     * @return {@link Boolean}
     */
    public Boolean removePermission(String roleId, String permissionId) {
        QueryWrapper<RolePermission> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id", roleId)
                .eq("permission_id", permissionId);
        return this.remove(queryWrapper);
    }

    /**
     * 通过角色Id和权限Id获取角色权限记录
     *
     * @param roleId       角色Id
     * @param permissionId 权限Id
     * @return {@link RolePermission}
     */
    private RolePermission getByRoleIdAndPermissionId(String roleId, String permissionId) {
        QueryWrapper<RolePermission> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id", roleId)
                .eq("permission_id", permissionId);
        return this.getOne(queryWrapper);
    }
}
